package org.cogaen.java2d.xml;

import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;

public class TextParser {

	private static final String TEXT_ELEMENT = "text";
	private static final String FONT_ATTRIB = "font";
	private static final String COLOR_ATTRIB = "color";
	private static final String X_OFFSET_ATTRIB = "hoffset";
	private static final String Y_OFFSET_ATTRIB = "voffset";
	private static final String NAME_SPACE = null;
	
	private String text;
	private String colorName;
	private String fontName;
	private double xOffset;
	private double yOffset;

	public static boolean isStart(XMLStreamReader reader) {
		return reader.isStartElement() && TEXT_ELEMENT.equals(reader.getLocalName());
	}
	
	public static ResetableStreamFilter createFilter(String textName) {
		return new ElementFilter(TEXT_ELEMENT, textName);
	}
	
	public void parse(XMLStreamReader reader) throws XMLStreamException, ParseException {
		if (isStart(reader)) {
			parseFont(reader);
			parseColor(reader);
			parseOffset(reader);
			parseText(reader);
		} else {
			throw new ParseException("xml element not found");
		}
	}
	
	private void parseOffset(XMLStreamReader reader) throws ParseException {
		String str = reader.getAttributeValue(null, X_OFFSET_ATTRIB);
		
		if (str == null) {
			this.xOffset = 0;
			return;
		}
		
		try {
			this.xOffset = Double.parseDouble(str);
		} catch (NumberFormatException e) {
			this.xOffset = 0;
			throw new ParseException("invalid offset value '" + str + "'");
		}		
		
		str = reader.getAttributeValue(null, Y_OFFSET_ATTRIB);
		
		if (str == null) {
			this.yOffset = 0;
			return;
		}
		
		try {
			this.yOffset = Double.parseDouble(str);
		} catch (NumberFormatException e) {
			this.yOffset = 0;
			throw new ParseException("invalid offset value '" + str + "'");
		}		
		
	}

	private void parseFont(XMLStreamReader reader) {
		this.fontName = reader.getAttributeValue(NAME_SPACE, FONT_ATTRIB);
	}

	private void parseColor(XMLStreamReader reader) {
		this.colorName = reader.getAttributeValue(NAME_SPACE, COLOR_ATTRIB);
	}
	
	private void parseText(XMLStreamReader reader) throws XMLStreamException, ParseException {

		this.text = null;
		
		while (reader.hasNext()) {
			int event = reader.next();
			
			switch (event) {
			case XMLStreamConstants.CHARACTERS:
				this.text = reader.getText();
				break;

			case XMLStreamConstants.START_ELEMENT:
				throw new ParseException("unexpected new element '" + reader.getLocalName() + "'");
				
			case XMLStreamConstants.END_DOCUMENT:
				throw new ParseException("unexepcted end of document");
				
			case XMLStreamConstants.END_ELEMENT:
				if (TEXT_ELEMENT.equals(reader.getLocalName())) {
					return;
				} else {
					throw new ParseException("unexpected end of element '" + reader.getLocalName() + "'");					
				}
			}			
		}		
	}

	public String getText() {
		return text;
	}

	public String getColorName() {
		return colorName;
	}

	public String getFontName() {
		return fontName;
	}

	public double getOffsetX() {
		return xOffset;
	}

	public double getOffsetY() {
		return yOffset;
	}
	
}
